﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace SharpMUSH
{
    static public class Config
    {
        // Define constant values for categories (mostly saves on typing)
        const OptionCategory ESSENTIALS = OptionCategory.ESSENTIALS;
        const OptionCategory LIMITS = OptionCategory.LIMITS;
        const OptionCategory DUMP = OptionCategory.DUMP;
        const OptionCategory FILENAMES = OptionCategory.FILENAMES;
        const OptionCategory LOGGING = OptionCategory.LOGGING;
        const OptionCategory LOGINS = OptionCategory.LOGINS;
        const OptionCategory COMMANDS = OptionCategory.COMMANDS;
        const OptionCategory ATTRIBUTES = OptionCategory.ATTRIBUTES;
        const OptionCategory COSMETIC = OptionCategory.COSMETIC;
        const OptionCategory FLAGS = OptionCategory.FLAGS;


        static public string Path = "game/mush.cnf"; // Location of mush.cnf
        
        // Dictionary to hold all our config options
        static public Dictionary<string, Option> Options = new Dictionary<string, Option>();

        // List of default values
        static public List<Option> Defaults = new List<Option>()
        {
            new Option("mud_name SharpMUSH", Perm.ANY, Perm.GOD, ESSENTIALS, true),
            new Option("mud_url", Perm.ANY, Perm.GOD, ESSENTIALS, true),
            new Option("port 4000", Perm.ANY, Perm.GOD, ESSENTIALS, true),
            new Option("ip_addr", ESSENTIALS, true),
            new Option("use_dns", Perm.GOD, Perm.GOD, ESSENTIALS, true),
            new Option("input_database data/indb", Perm.GOD, Perm.GOD, ESSENTIALS, true),
            new Option("output_database data/outdb", Perm.GOD, Perm.GOD, ESSENTIALS, true),
            new Option("crash_database data/crash", Perm.GOD, Perm.GOD, ESSENTIALS, true),
            new Option("mail_database data/mail", Perm.GOD, Perm.GOD, ESSENTIALS, true),
            new Option("chat_database data/chatdb", Perm.GOD, Perm.GOD, ESSENTIALS, true),
            new Option("player_start 0", ESSENTIALS, true),
            new Option("master_room 2", ESSENTIALS, true),
            new Option("base_room 0", ESSENTIALS, true),
            new Option("ancestor_room -1", ESSENTIALS, true),
            new Option("ancestor_exit -1", ESSENTIALS, true),
            new Option("ancestor_thing -1", ESSENTIALS, true),
            new Option("ancestor_player -1", ESSENTIALS, true),
            new Option("default_home 0", ESSENTIALS, true),
            new Option("access_file access.cnf", Perm.GOD, Perm.GOD, ESSENTIALS, true),
            new Option("names_file names.cnf", Perm.GOD, Perm.GOD, ESSENTIALS, true),
            new Option("money_singular Token", Perm.ANY, Perm.WIZARD, LIMITS, true),
            new Option("money_plural Tokens", Perm.ANY, Perm.WIZARD, LIMITS, true),
            new Option("idle_timeout 0m", Perm.ANY, Perm.WIZARD, LIMITS, true),
            new Option("unconnected_idle_timeout 5m", Perm.ANY, Perm.WIZARD, LIMITS, true),
            new Option("keepalive_timeout 5m", Perm.ANY, Perm.WIZARD, LIMITS, true),
            new Option("max_logins 120", LIMITS, true),
            new Option("guest_dbref", LIMITS, true),
            new Option("starting_money 150", Perm.ROYAL, Perm.WIZARD, LIMITS, true),
            new Option("paycheck 50", Perm.ROYAL, Perm.WIZARD, LIMITS, true),
            new Option("starting_quota 20", Perm.ROYAL, Perm.WIZARD, LIMITS, true),
            new Option("player_queue_limit 100", LIMITS, true),
            new Option("queue_chunk 3", LIMITS, true),
            new Option("active_queue_chunk 1", LIMITS),
            new Option("function_recursion_limit 50", LIMITS, true),
            new Option("function_invocation_limit 50", LIMITS, true),
            new Option("max_player_chans 0", LIMITS, true),
            new Option("max_depth 10", LIMITS, true),
            new Option("chan_cost 1000", Perm.ANY, Perm.WIZARD, LIMITS, true),
            new Option("whisper_loudness 100", Perm.ANY, Perm.WIZARD, LIMITS, true),
            new Option("max_dbref 0", LIMITS, true),
            new Option("max_attrs_per_obj 2048", LIMITS, true),
            new Option("mail_limit 300", LIMITS, true),
            new Option("kill_min_cost 10", Perm.ANY, Perm.WIZARD, LIMITS, true),
            new Option("kill_default_cost 10", Perm.ANY, Perm.WIZARD, LIMITS, true),
            new Option("kill_bonus 50", Perm.ANY, Perm.WIZARD, LIMITS, true),
            new Option("find_cost 100", Perm.ANY, Perm.WIZARD, LIMITS, true),
            new Option("quota_cost 1", Perm.ANY, Perm.WIZARD, LIMITS, true),
            new Option("queue_cost 10", Perm.ANY, Perm.WIZARD, LIMITS, true),
            new Option("queue_loss 63", Perm.ANY, Perm.WIZARD, LIMITS, true),
            new Option("room_cost 10", Perm.ANY, Perm.WIZARD, LIMITS, true),
            new Option("object_cost 10", Perm.ANY, Perm.WIZARD, LIMITS, true),
            new Option("link_cost 1", Perm.ANY, Perm.WIZARD, LIMITS, true),
            new Option("exit_cost 1", Perm.ANY, Perm.WIZARD, LIMITS, true),
            new Option("purge_interval 10m", LIMITS, true),
            new Option("dbck_interval 10m", LIMITS, true),
            new Option("warn_interval 1h", LIMITS, true),
            new Option("float_precision 6", Perm.ANY, Perm.GOD, LIMITS, true),
            new Option("log_wipe_passwd stab!", Perm.GOD, Perm.GOD, LIMITS, true),
            new Option("player_name_len 16", LIMITS, true),
            new Option("max_aliases 3", LIMITS, true),
            new Option("use_quota yes", LIMITS, true),
            new Option("dump_interval 1h", Perm.ANY, Perm.GOD, DUMP, true),
            new Option("forking_dump yes", Perm.ANY, Perm.GOD, DUMP, true),
            new Option("dump_warning_5min GAME: Database save in 5 minutes.", Perm.ANY, Perm.WIZARD, DUMP, true),
            new Option("dump_warning_1min GAME: Database save in 1 minute.", Perm.ANY, Perm.WIZARD, DUMP, true),
            new Option("dump_message GAME: Saving Databases. Game may freeze for a moment.", Perm.ANY, Perm.WIZARD, DUMP, true),
            new Option("dump_complete GAME: Save Complete.", Perm.ANY, Perm.GOD, DUMP, true),
            new Option("connect_file txt/connect.txt", FILENAMES, true),
            new Option("motd_file txt/motd.txt", FILENAMES, true),
            new Option("wizmotd_file txt/wizmotd.txt", FILENAMES, true),
            new Option("quit_file txt/quit.txt", FILENAMES, true),
            new Option("newuser_file txt/newuser.txt", FILENAMES, true),
            new Option("down_file txt/down.txt", FILENAMES, true),
            new Option("register_create_file txt/register.txt", FILENAMES, true),
            new Option("guest_file txt/guest.txt", FILENAMES, true),
            new Option("full_file txt/full.txt", FILENAMES, true),
            new Option("error_log log/mush.log", LOGGING, true),
            new Option("connect_log log/connect.log", LOGGING, true),
            new Option("wizard_log log/wizard.log", LOGGING, true),
            new Option("checkpt_log log/checkpt.log", LOGGING, true),
            new Option("trace_log log/trace.log", LOGGING, true),
            new Option("command_log log/command.log", LOGGING, true),
            new Option("log_commands no", LOGGING, true),
            new Option("log_forces yes", LOGGING, true),
            new Option("logins yes", LOGINS, true),
            new Option("guests yes", LOGINS, true),
            new Option("player_creation yes", LOGINS, true),
            new Option("reverse_shs yes", LOGINS, true),
            new Option("room_connects yes", LOGINS, true),
            new Option("safer_ufun yes", COMMANDS, true),
            new Option("function_side_effects yes", COMMANDS, true),
            new Option("noisy_whisper no", COMMANDS, true),
            new Option("noisy_cemit no", COMMANDS, true),
            new Option("possessive_get yes", COMMANDS, true),
            new Option("possessive_get_d no", COMMANDS, true),
            new Option("really_safe yes", COMMANDS, true),
            new Option("zone_control_zmp_only yes", COMMANDS, true),
            new Option("destroy_possessions yes", COMMANDS, true),
            new Option("link_to_object yes", COMMANDS, true),
            new Option("owner_queues no", COMMANDS, true),
            new Option("wiz_noaenter no", COMMANDS, true),
            new Option("full_invis no", COMMANDS, true),
            new Option("empty_attrs yes", COMMANDS, true),
            new Option("adestroy no", ATTRIBUTES, true),
            new Option("amail no", ATTRIBUTES, true),
            new Option("player_listen yes", ATTRIBUTES, true),
            new Option("player_ahear yes", ATTRIBUTES, true),
            new Option("startups yes", ATTRIBUTES, true),
            new Option("read_remote_desc no", ATTRIBUTES, true),
            new Option("ansi_name yes", COSMETIC, true),
            new Option("comma_exit_list yes", COSMETIC, true),
            new Option("count_all no", COSMETIC, true),
            new Option("exits_connect_rooms no", COSMETIC, true),
            new Option("wizwall_prefix Broadcast:", COSMETIC, true),
            new Option("rwall_prefix Admin:", COSMETIC, true),
            new Option("wall_prefix Announcement:", COSMETIC, true),
            new Option("announce_connects yes", COSMETIC, true),
            new Option("player_name_spaces no", COSMETIC, true),
            new Option("flags_on_exmaine yes", COSMETIC, true),
            new Option("ex_public_attribs yes", COSMETIC, true),
            new Option("blind_page no", COSMETIC, true),
            new Option("page_aliases no", COSMETIC, true),
            new Option("chat_strip_quote yes", COSMETIC, true),
            new Option("newline_one_char yes", COSMETIC, true),
            new Option("only_ascii_in_names yes", COSMETIC, true),
            new Option("exit_flags", FLAGS, true),
            new Option("room_flags", FLAGS, true),
            new Option("player_flags enter_ok inherit no_command ansi", FLAGS, true),
            new Option("thing_flags no_command", FLAGS, true),
            new Option("channel_flags player", FLAGS, true)  
        };

        static public bool Load()
        {
            Console.WriteLine("Attempting to load mush.cnf...");
            if (File.Exists(Convert.SafePath(Path)))
            {
                try
                {
                    Console.WriteLine("Found mush.cnf!");
                    StreamReader file = new StreamReader(Convert.SafePath(Path));
                    string line = string.Empty;

                    while ((line = file.ReadLine()) != null)
                    {
                        Console.WriteLine("Reading: {0}", line);

                        if (!line.StartsWith("#") && line.Trim() != "")
                        {
                            // Parse lines here to figure out if we need to do something
                            // special with them.
                            // Get option name and place string into dictionary
                            Option temp = new Option(line);
                            if (temp.Name == "help_command")
                            {
                                // Handle Help Commands.
                            }
                            else if (temp.Name == "ahelp_command")
                            {
                                // Handle Admin Help Commands.
                            }
                            else if (temp.Name == "restrict_command")
                            {
                                // Handle command restrictions
                            }
                            else
                            {

                                Options.Add(temp.Name, temp);
                                Console.WriteLine("  {0} -> {1}", temp.Name.ToUpper(), temp.GetString());
                            }
                        }
                    }

                    Console.WriteLine("Done loading mush.cnf!");
                    return true;
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    return false;
                }
            }
            else
            {
                Console.WriteLine("Could not find mush.cnf!");
                return false;
            }
        }


    }
}
